"""
分型描述：
fenxing：维护fx,在上涨中，顶分型 low<prelow hogh<prehigh  底分型反之
fenxing0:维护fx,不但要满足分型高低点要求，还要满足close价涨跌的要求  也就是
fenxing_box：维护fx，open close-->low,high 在上涨中 顶分型：1)高点更高，低点更低 2）创新高 但是低点更低  close低 且有一定空间
fenxing_byprice：维护fx,参数gap,price都是bar中的字段；顶分型：反弹gap 下认为底分型，饭反转了
fenxing_byclose：维护fx 参数gap是点数 顶分型：close 反弹gapd点
fenxing_bychan:缠论中的k线合并分型，重在返回fx,low,high  out不需要的地方可以

分型的笔  见bi.py
"""
class fenxing:
    def __init__(self):
        self.prebar=None
        self.fx=None
    def oncalc(self,b,timekey=None):
        if self.prebar!=None:
            if self.fx!=None:
                if self.fx<=-1:
                    if b["high"]>self.prebar["high"] and b["low"]>self.prebar["low"]:
                        self.fx=2
                    else:
                        self.fx = -1
                elif self.fx>=1:
                    if b["high"] < self.prebar["high"] and b["low"] < self.prebar["low"]:
                        self.fx = -2
                    else:
                        self.fx = 1
            else:
                if b["high"]>self.prebar["high"] and b["low"]>self.prebar["low"]:
                    self.fx=1
                elif b["high"]<self.prebar["high"] and b["low"]<self.prebar["low"]:
                    self.fx=-1
        self.prebar=b
        return self.fx
class fenxing_box:
    def __init__(self):
        self.prebar=None
        self.fx=None
    def oncalc(self,b,timekey=None):
        if b["open"] > b["close"]:
            low =b["close"]
            high=b["open"]
        else:
            high = b["close"]
            low = b["open"]
        if self.prebar!=None:
            if self.fx!=None:
                if self.fx<=-1:
                    if high>self.prebar[1] and low>self.prebar[0]:
                        self.fx=2
                    elif high>self.prebar[1] and low<self.prebar[0]:
                        delta1=high-self.prebar[1]
                        delta2=self.prebar[1]-self.prebar[0]
                        delta3=self.prebar[0]-low
                        if delta1>delta2 and delta1>delta3 and b["open"]<b["close"]:
                            self.fx=2
                        else:
                            self.fx=-1
                    else:
                        self.fx = -1
                elif self.fx>=1:
                    if high < self.prebar[1] and low < self.prebar[0]:
                        self.fx = -2
                    elif high>self.prebar[1] and low<self.prebar[0]:
                        delta1=high-self.prebar[1]
                        delta2=self.prebar[1]-self.prebar[0]
                        delta3=self.prebar[0]-low
                        if delta1<delta3 and delta2<delta3 and b["close"]<b["open"]:
                            self.fx=-2
                        else:
                            self.fx=1
                    else:
                        self.fx = 1
            else:
                if high>self.prebar[1] and low>self.prebar[0]:
                    self.fx=1
                elif high<self.prebar[1] and low<self.prebar[0]:
                    self.fx=-1
        self.prebar=(low,high)
        return self.fx
class fenxing_byprice:
    def __init__(self,price="close",gap=None):
        self.prebar=None
        self.fx=None
        self.gap=gap
        self.price=price
    def oncalc(self,b,timekey=None):
        if self.prebar!=None:
            t0=b[self.price]
            if self.fx!=None:
                if self.fx<=-1:
                    if self.gap==None:
                        t=self.prebar + b[self.gap]
                    else:
                        t=self.prebar
                    if t0>t:
                        self.fx=2
                    else:
                        self.fx = -1
                elif self.fx>=1:
                    if self.gap==None:
                        t=self.prebar - b[self.gap]
                    else:
                        t=self.prebar
                    if t0 < t:
                        self.fx = -2
                    else:
                        self.fx = 1
            else:
                if t0>self.prebar:
                    self.fx=1
                elif t0<self.prebar:
                    self.fx=-1
        self.prebar=t0
        return self.fx
class fenxing_byclose:
    def __init__(self,gap=0):
        self.prebar=None
        self.fx=None
        self.gap=gap
    def oncalc(self,b,timekey=None):
        if self.prebar!=None:
            if self.fx!=None:
                if self.fx<=-1:
                    if b>self.prebar+self.gap:
                        self.fx=2
                    else:
                        self.fx = -1
                elif self.fx>=1:
                    if b < self.prebar-self.gap:
                        self.fx = -2
                    else:
                        self.fx = 1
            else:
                if b>self.prebar:
                    self.fx=1
                elif b<self.prebar:
                    self.fx=-1
        self.prebar=b
        return self.fx
class fenxing0:
    def __init__(self):
        self.prebar=None
        self.fx=None
    def oncalc(self,b,timekey=None):
        if self.prebar!=None:
            if self.fx!=None:
                if self.fx<=-1:
                    if b["high"]>self.prebar["high"] and b["low"]>self.prebar["low"] and b["close"]>self.prebar["close"]:
                        self.fx=2
                    else:
                        self.fx = -1
                elif self.fx>=1:
                    if b["high"] < self.prebar["high"] and b["low"] < self.prebar["low"] and b["close"]<self.prebar["close"]:
                        self.fx = -2
                    else:
                        self.fx = 1
            else:
                if b["high"]>self.prebar["high"] and b["low"]>self.prebar["low"] and b["close"]>self.prebar["close"]:
                    self.fx=1
                elif b["high"]<self.prebar["high"] and b["low"]<self.prebar["low"] and b["close"]<self.prebar["close"]:
                    self.fx=-1
        self.prebar=b
        return self.fx

class fenxing_bychan:
    def __init__(self):
        self.fx=None
        self.prebar=[None,None]

    def oncalc(self, b,timekey=None):
        if self.fx>=1:#涨  找顶分型
            low=b["low"]
            high=b["high"]
            if low>=self.prebar[0] and high>=self.prebar[1]:#高低点都高
                self.prebar = [low, high]
            elif low<self.prebar[0] and high<self.prebar[1]:#顶分型   高低点都低
                self.fx = -2
                self.prebar = [low, high]
            elif low>=self.prebar[0] and high<=self.prebar[1]:#内包含
                self.prebar[0]=low
            elif low<=self.prebar[0] and high>=self.prebar[1]:#外包含
                self.prebar[1]=high
        elif self.fx<=-1:#跌 找底分型
            low = b["low"]
            high = b["high"]
            if low <= self.prebar[0] and high <= self.prebar[1]:  # 高低点都低
                self.prebar = [low, high]
            elif low > self.prebar[0] and high > self.prebar[1]:  # 底分型   高低点都高
                self.fx = 2
                self.prebar = [low, high]
            elif low >= self.prebar[0] and high <= self.prebar[1]:  # 内包含
                self.prebar[1] = high
            elif low <= self.prebar[0] and high >= self.prebar[1]:  # 外包含
                self.prebar[0] = low
        else:
            if b["open"]<b["close"]:
                self.fx=1
            else:
                self.fx=-1
            self.prebar=[b["low"],b["high"]]

        return self.fx,self.prebar[0],self.prebar[1]
